#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MCP Calculator Server - Enhanced Calculator Engine

提供高级数学计算功能的核心引擎
"""

import math
import re
import ast
import operator
from decimal import Decimal, getcontext
from typing import Union, Dict, Any, List
from functools import lru_cache
import logging

# 设置高精度计算
getcontext().prec = 50

logger = logging.getLogger(__name__)

class CalculatorEngine:
    """增强的计算器引擎"""
    
    def __init__(self):
        # 支持的运算符
        self.operators = {
            ast.Add: operator.add,
            ast.Sub: operator.sub,
            ast.Mult: operator.mul,
            ast.Div: operator.truediv,
            ast.Pow: operator.pow,
            ast.Mod: operator.mod,
            ast.USub: operator.neg,
            ast.UAdd: operator.pos,
        }
        
        # 支持的数学函数
        self.math_functions = {
            'sin': math.sin,
            'cos': math.cos,
            'tan': math.tan,
            'asin': math.asin,
            'acos': math.acos,
            'atan': math.atan,
            'sinh': math.sinh,
            'cosh': math.cosh,
            'tanh': math.tanh,
            'log': math.log,
            'log10': math.log10,
            'log2': math.log2,
            'ln': math.log,
            'exp': math.exp,
            'sqrt': math.sqrt,
            'abs': abs,
            'ceil': math.ceil,
            'floor': math.floor,
            'round': round,
            'factorial': math.factorial,
            'degrees': math.degrees,
            'radians': math.radians,
            'cbrt': lambda x: x ** (1/3),
            'gcd': math.gcd,
            'lcm': lambda a, b: abs(a * b) // math.gcd(a, b) if a != 0 and b != 0 else 0,
            'min': min,
            'max': max,
        }
        
        # 数学常数
        self.constants = {
            'pi': math.pi,
            'e': math.e,
            'tau': math.tau,
            'inf': math.inf,
            'phi': (1 + math.sqrt(5)) / 2,  # 黄金比例
        }
    
    def basic_operation(self, a: float, b: float, operation: str) -> Dict[str, Any]:
        """执行基本运算"""
        try:
            operations = {
                'add': (operator.add, '+'),
                'subtract': (operator.sub, '-'),
                'multiply': (operator.mul, '×'),
                'divide': (operator.truediv, '÷'),
                'power': (operator.pow, '^'),
                'modulo': (operator.mod, '%'),
            }
            
            if operation not in operations:
                return {
                    'success': False,
                    'error': f'不支持的运算类型: {operation}',
                    'result': None
                }
            
            op_func, op_symbol = operations[operation]
            
            # 特殊处理除零
            if operation == 'divide' and b == 0:
                return {
                    'success': False,
                    'error': '除数不能为零',
                    'result': None
                }
            
            # 特殊处理负数的偶数次幂
            if operation == 'power' and a < 0 and not isinstance(b, int):
                return {
                    'success': False,
                    'error': '负数不能进行非整数次幂运算',
                    'result': None
                }
            
            result = op_func(a, b)
            
            return {
                'success': True,
                'error': None,
                'result': result,
                'expression': f'{a} {op_symbol} {b} = {result}',
                'operation': operation
            }
            
        except Exception as e:
            logger.error(f'基本运算错误: {e}')
            return {
                'success': False,
                'error': f'运算失败: {str(e)}',
                'result': None
            }
    
    def validate_expression(self, expression: str) -> Dict[str, Any]:
        """验证表达式的安全性和正确性"""
        if not expression or not expression.strip():
            return {'valid': False, 'error': '表达式不能为空'}
        
        expression = expression.strip()
        
        # 检查危险字符和关键词
        dangerous_patterns = [
            r'__.*__',  # 双下划线方法
            r'import\s+',  # import语句
            r'exec\s*\(',  # exec函数
            r'eval\s*\(',  # eval函数
            r'open\s*\(',  # 文件操作
            r'file\s*\(',  # 文件操作
            r'input\s*\(',  # 输入函数
            r'print\s*\(',  # 输出函数
        ]
        
        for pattern in dangerous_patterns:
            if re.search(pattern, expression, re.IGNORECASE):
                return {'valid': False, 'error': '表达式包含不安全的内容'}
        
        # 检查括号匹配
        if expression.count('(') != expression.count(')'):
            return {'valid': False, 'error': '括号不匹配'}
        
        # 检查允许的字符（更宽松的检查）
        allowed_chars = r'[0-9a-zA-Z+\-*/().,\s_^]'
        if not re.match(f'^{allowed_chars}+$', expression):
            return {'valid': False, 'error': '表达式包含不允许的字符'}
        
        return {'valid': True, 'error': None}
    
    def preprocess_expression(self, expression: str) -> str:
        """预处理表达式，替换函数和常数"""
        # 替换数学常数
        for const_name, const_value in self.constants.items():
            expression = re.sub(r'\b' + const_name + r'\b', str(const_value), expression, flags=re.IGNORECASE)
        
        # 不需要预处理函数，直接在安全字典中提供
        return expression
    
    @lru_cache(maxsize=1000)
    def evaluate_expression(self, expression: str) -> Dict[str, Any]:
        """计算数学表达式（带缓存）"""
        try:
            # 验证表达式
            validation = self.validate_expression(expression)
            if not validation['valid']:
                return {
                    'success': False,
                    'error': validation['error'],
                    'result': None
                }
            
            # 预处理表达式
            processed_expr = self.preprocess_expression(expression)
            
            # 创建安全的执行环境
            safe_dict = {
                '__builtins__': {},
                'math': math,
                **self.math_functions,
                **self.constants
            }
            
            # 计算结果
            result = eval(processed_expr, safe_dict)
            
            # 检查结果是否有效
            if math.isnan(result):
                return {
                    'success': False,
                    'error': '计算结果为NaN（非数字）',
                    'result': None
                }
            
            if math.isinf(result):
                return {
                    'success': False,
                    'error': '计算结果为无穷大',
                    'result': None
                }
            
            return {
                'success': True,
                'error': None,
                'result': result,
                'expression': expression,
                'processed_expression': processed_expr
            }
            
        except ZeroDivisionError:
            return {
                'success': False,
                'error': '除零错误',
                'result': None
            }
        except ValueError as e:
            return {
                'success': False,
                'error': f'数值错误: {str(e)}',
                'result': None
            }
        except SyntaxError:
            return {
                'success': False,
                'error': '语法错误: 表达式格式不正确',
                'result': None
            }
        except Exception as e:
            logger.error(f'表达式计算错误: {e}')
            return {
                'success': False,
                'error': f'计算失败: {str(e)}',
                'result': None
            }
    
    def get_function_help(self, function_name: str = None) -> str:
        """获取函数帮助信息"""
        if function_name:
            if function_name in self.math_functions:
                func = self.math_functions[function_name]
                return f"{function_name}: {func.__doc__ or '数学函数'}"
            else:
                return f"未知函数: {function_name}"
        else:
            help_text = "可用的数学函数:\n"
            for name in sorted(self.math_functions.keys()):
                help_text += f"  - {name}\n"
            help_text += "\n可用的数学常数:\n"
            for name, value in self.constants.items():
                help_text += f"  - {name} = {value}\n"
            return help_text
    
    def clear_cache(self):
        """清除计算缓存"""
        self.evaluate_expression.cache_clear()
        logger.info("计算缓存已清除")
    
    def get_cache_info(self) -> Dict[str, Any]:
        """获取缓存信息"""
        cache_info = self.evaluate_expression.cache_info()
        return {
            'hits': cache_info.hits,
            'misses': cache_info.misses,
            'maxsize': cache_info.maxsize,
            'currsize': cache_info.currsize,
            'hit_rate': cache_info.hits / (cache_info.hits + cache_info.misses) if (cache_info.hits + cache_info.misses) > 0 else 0
        }